package com.vf.s.mvc.biz.controller;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPOutputStream;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.CaseInsensitiveContainerFactory;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.dialect.Sqlite3Dialect;
import com.jfinal.plugin.druid.DruidPlugin;

public class TilesetToDb {

	public static void dataToDB(String filePath) {
		List<Record> recordList = new LinkedList<Record>();
		File file = new File(filePath);
		listFiles(filePath, file, recordList);
		if (recordList.size() > 0) {
			saveRecord(recordList);
			recordList.clear();
		}
	}

	public static void listFiles(String filePath, File srcFile, List<Record> recordList) {
		if (srcFile.isDirectory()) {
			for (File file : srcFile.listFiles()) {
				listFiles(filePath, file, recordList);
			}
		} else {
			if (srcFile.getName().contains("json")) {
				try {

					JSONObject json = JSONObject.parseObject(readJsonFile(srcFile));
					Map<String, Object> jsonMap = new HashMap<String, Object>();

					String fileName = srcFile.getName();
					long start = System.currentTimeMillis();
					replace(jsonMap, json);
					long end = System.currentTimeMillis();
					System.out.println(fileName + "时间=" + (end - start));

					String fileTyle = fileName.substring(fileName.lastIndexOf("."), fileName.length());

					String fileUrl = srcFile.getPath().replace(filePath, "");
					fileUrl = fileUrl.replace("+", "").replace("./", "").replace("/", "").replace("\\", "");

					Record record = new Record();
					record.set("id", fileUrl);
					record.set("format", fileTyle);
					record.set("content", gzip(JSONObject.toJSONString(jsonMap).getBytes()));

					recordList.add(record);
					if (recordList.size() % 200 == 0) {
						saveRecord(recordList);
						recordList.clear();
					}
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
				}
			} else {
				String fileName = srcFile.getName();
				String fileTyle = fileName.substring(fileName.lastIndexOf("."), fileName.length());
				Record record = new Record();
				fileName = fileName.replace("+", "").replace("./", "").replace("/", "").replace("_", "");
				record.set("id", fileName);
				record.set("format", fileTyle);

				long start = System.currentTimeMillis();
				record.set("content", fileToGZip(srcFile));
				long end = System.currentTimeMillis();
				System.out.println(fileName + "时间=" + (end - start));
				recordList.add(record);
				if (recordList.size() % 200 == 0) {
					saveRecord(recordList);
					recordList.clear();
				}

			}
		}
	}

	public static void saveRecord(List<Record> recordList) {
		long start = System.currentTimeMillis();
		Db.batchSave("vf_tileset", recordList, recordList.size());
		long end = System.currentTimeMillis();
		System.out.println("插入数据:【" + recordList.size() + "】--耗时=" + (end - start));
	}

	/**
	 * @Desc : gzip压缩
	 * @Author : ZRP
	 * @Params: [data]
	 * @Return: byte[]
	 * @Date : 2017/11/9 9:43
	 */
	public static byte[] gzip(byte[] data) throws Exception {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		GZIPOutputStream gzip = new GZIPOutputStream(bos);
		gzip.write(data);
		gzip.finish();
		gzip.close();
		byte[] ret = bos.toByteArray();
		bos.close();
		return ret;
	}

	public static byte[] fileToGZip(File file) {
		try {
			return gzip(fileConvertToByteArray(file));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 把一个文件转化为byte字节数组。
	 *
	 * @return
	 */
	public static byte[] fileConvertToByteArray(File file) {
		byte[] data = null;
		try {
			FileInputStream fis = new FileInputStream(file);
			ByteArrayOutputStream baos = new ByteArrayOutputStream();

			int len;
			byte[] buffer = new byte[1024];
			while ((len = fis.read(buffer)) != -1) {
				baos.write(buffer, 0, len);
			}
			data = baos.toByteArray();
			fis.close();
			baos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return data;
	}

	public static void replace(Map<String, Object> map, JSONObject item) {

		// 循环转换
		Iterator<String> it = item.keySet().iterator();
		while (it.hasNext()) {
			String key = it.next();
			if (StrKit.equals("url", key)) {
				String fileUrl = item.getString(key);
				if (fileUrl.contains("json")) {
					fileUrl = fileUrl.replace("+", "").replace("./", "").replace("/", "");
				} else {
					fileUrl = fileUrl.replace("+", "").replace("./", "").replace("/", "").replace("_", "");
				}
				map.put(key, "./tileset?id=" + fileUrl);
			} else if (StrKit.equals("children", key)) {
				JSONArray arr = item.getJSONArray(key);
				List<Object> nextList = new LinkedList<Object>();
				for (int i = 0; i < arr.size(); i++) {
					Map<String, Object> children = new HashMap<String, Object>();
					replace(children, arr.getJSONObject(i));
					nextList.add(children);
				}
				map.put(key, nextList);
			} else {
				if (item.get(key) instanceof JSONObject && item.keySet().size() > 0) {
					Map<String, Object> nextMap = new HashMap<String, Object>();
					replace(nextMap, item.getJSONObject(key));
					map.put(key, nextMap);
				} else {
					map.put(key, item.get(key));
				}
			}
		}
	}

	// 读取json文件
	public static String readJsonFile(File jsonFile) {
		String jsonStr = "";
		try {
			FileReader fileReader = new FileReader(jsonFile);
			Reader reader = new InputStreamReader(new FileInputStream(jsonFile), "utf-8");
			int ch = 0;
			StringBuffer sb = new StringBuffer();
			while ((ch = reader.read()) != -1) {
				sb.append((char) ch);
			}
			fileReader.close();
			reader.close();
			jsonStr = sb.toString();
			return jsonStr;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}

	public static void main(String[] args) {

		long start = System.currentTimeMillis();
		System.out.println("开始时间=" + start);

		DruidPlugin dp = new DruidPlugin("jdbc:sqlite:D:\\database\\sqllite\\tileset.db", "", "");
		dp.setDriverClass("org.sqlite.JDBC");
		dp.start();
		ActiveRecordPlugin arp = new ActiveRecordPlugin(dp);
		arp.setDialect(new Sqlite3Dialect()); // 指定 Dialect
		arp.setShowSql(true);
		arp.setContainerFactory(new CaseInsensitiveContainerFactory(true));
		arp.start();

		long dbTime = System.currentTimeMillis();
		System.out.println("连接db花费时间=" + (dbTime - start));

		dataToDB("E:\\tools\\out\\QJ2\\");
		long end = System.currentTimeMillis();
		System.out.println("花费时间=" + (end - start));
	}

}
